﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace NetNames {

    /// <summary>
    /// A static class that provides methods and extension methods for resolving
    /// member names from instances and derivatives of <see cref="T:LambdaExpression"/>.
    /// </summary>
    public static class MemberName {

        internal static MemberNameResolver NameResolver {
            get {
                if (null == _NameResolver) _NameResolver = new MemberNameResolver();
                return _NameResolver;
            }
            set {
                if (null == value) throw new ArgumentNullException("NameResolver");
                _NameResolver = value;
            }
        }
        private static MemberNameResolver _NameResolver;

        /// <summary>
        /// Gets the name of the member used in the <paramref name="expression"/>.
        /// </summary>
        /// <param name="expression">
        /// The <see cref="T:LambdaExpression"/> that calls the class member
        /// whose name should be returned.
        /// </param>
        /// <returns>
        /// The name of the member used in the <paramref name="expression"/>.
        /// </returns>        
        public static string Of(LambdaExpression expression) {
            return NameResolver.Resolve(expression);
        }

        /// <summary>
        /// Gets the name of the member used in the <paramref name="selector"/>.
        /// </summary>
        /// <param name="selector">
        /// The expression that calls the class member
        /// whose name should be returned.
        /// </param>
        /// <returns>
        /// The name of the member used in the <paramref name="selector"/>.
        /// </returns>        
        public static string Of<T, TResult>(Expression<Func<T, TResult>> selector) {
            return Of((LambdaExpression)selector);
        }

        /// <summary>
        /// Gets the name of the member used in the <paramref name="selector"/>.
        /// </summary>
        /// <param name="selector">
        /// The expression that calls the class member
        /// whose name should be returned.
        /// </param>
        /// <returns>
        /// The name of the member used in the <paramref name="selector"/>.
        /// </returns>        
        public static string Of<T>(Expression<Action<T>> selector) {
            return Of((LambdaExpression)selector);
        }
    }
}
